package junior.util.address;

import junior.util.wrap.Scored;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class AddressIndexResult<T> {
	
	private final Address address;
	
	private final List<Pair<Address, T>> matchedIndexList;
	
	public AddressIndexResult(Address address){
		this.address = address;
		this.matchedIndexList = Collections.emptyList();
	}
	
	public AddressIndexResult(Address address, List<Pair<Address, T>> matchedList){
		this.address = address;
		this.matchedIndexList = matchedList;
	}

	public Address getAddress() {
		return address;
	}

	public List<Pair<Address, T>> getMatchedIndexList() {
		return matchedIndexList;
	}
	
	public T getBestMatch(final AddressIndexScorer<T> scorer){
		if(CollectionUtils.isEmpty(matchedIndexList)){
			return null;
		}
		
		final Map<Long, Integer> idCountMap = new TreeMap<Long, Integer>();
		final List<Scored<T>> scoredList = new ArrayList<Scored<T>>();
		
		for(final Pair<Address, T> pair: matchedIndexList){
			final long id = scorer.getId(pair.getRight());
			Integer idCount = idCountMap.get(id);
			if(idCount == null){
				idCountMap.put(id, 1);
			}else{
				idCountMap.put(id, idCount + 1);
			}
			final double score = scorer.score(address, pair.getLeft(), pair.getRight());
			scoredList.add(new Scored<T>(pair.getRight(), score));
		}
		
		Collections.sort(scoredList, new Comparator<Scored<T>>() {
			@Override
			public int compare(Scored<T> o1, Scored<T> o2) {
				int scoreR = Double.compare(o2.getScore(), o1.getScore());
				if(scoreR != 0){
					return scoreR;
				}else{
					Integer c1 = idCountMap.get(scorer.getId(o1.value));
					Integer c2 = idCountMap.get(scorer.getId(o2.value));
					return Integer.compare(c2, c1);
				}
			}
		});
		
		return scoredList.get(0).value;
	}
	
	
}
